﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace Nirvana
{
    class MaterialsRefCount
    {
        private Material material;
        private int count;
        public MaterialsRefCount(Material mat)
        {
            this.material = mat;
            this.count = 1;
        }

        public Material GetMaterial()
        {
            return this.material;
        }
        public int GetCount()
        {
            return this.count;
        }

        public void SetCount(int num)
        {
            this.count = num;
        }
    }
    public static class MaterialsTool
    {
        private static Dictionary<MaterialsEffect, MaterialsRefCount> matEffectMap = new Dictionary<MaterialsEffect, MaterialsRefCount>();
        private static Dictionary<Material, MaterialsEffect> _matMap = new Dictionary<Material, MaterialsEffect>();

        /// <summary>
        /// 获取对应特效的材质球，引用计数+1
        /// </summary>
        /// <param name="mat"></param>
        /// <returns></returns>
        public static Material Get(MaterialsEffect mat)
        {
            MaterialsRefCount _list;
            if(matEffectMap.TryGetValue(mat,out _list))
            {
                _list.SetCount(_list.GetCount() + 1);
                return _list.GetMaterial();
            }

            var newmat = mat.CreateMaterial();
            if (newmat == null) return null;
            matEffectMap.Add(mat, new MaterialsRefCount(newmat));
            _matMap.Add(newmat, mat);
            return newmat;
        }
        /// <summary>
        /// 释放对应特效材质球，引用计数-1
        /// </summary>
        /// <param name="mat"></param>
        public static void Release(Material mat)
        {
            MaterialsEffect _matEff;
            if(!_matMap.TryGetValue(mat,out _matEff))
            {
               // Debug.LogError("Can not find the material key.");
                return;
            }

            MaterialsRefCount _list;
            if (!matEffectMap.TryGetValue(_matEff, out _list))
            {
                Debug.LogError("Can not find the material reference.");
                return;
            }

            _list.SetCount(_list.GetCount() - 1);
            if(_list.GetCount() <= 0)
            {
                if (Application.isPlaying)
                {
                    UnityEngine.Object.Destroy(_list.GetMaterial());
                }
                else
                {
                    UnityEngine.Object.DestroyImmediate(_list.GetMaterial());
                }
                matEffectMap.Remove(_matEff);
                _matMap.Remove(mat);
            }
        }
#if UNITY_EDITOR
        /// <summary>
        /// 清除项目中执过的缓存
        /// </summary>
        [MenuItem("Nirvana/Render/Clear UI Effect Material Cache")]
        private static void Clear()
        {
            matEffectMap.Clear();
            _matMap.Clear();
            SceneView.RepaintAll();
        }
#endif

    }
}
